package com.vlyman.aop;

import com.alibaba.fastjson.JSONObject;
import com.vlyman.annotation.VlymanLog;
import com.vlyman.rtn.RtnResult;
import com.vlyman.utils.AspectUtil;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.lang.reflect.Method;
import java.util.Map;

/**
 * 类描述：
 *  统一日志切面
 * @author chenjs
 * @date 2018/9/19 22:46
 **/
@Aspect
@Slf4j
@Component
@Order(1)
public class VlymanLogAspect {

    /**
     * 方法描述：
     *   统一日志切入点，@VlymanLog
     *  @author chenjs
     *  @date 2018/9/20 10:05
     */
    @Pointcut("@annotation(com.vlyman.annotation.VlymanLog)")
    public void vlymanLogPointCut() {}

    /**
     * 方法描述：
     *   aop方式控制日志
     *  @author chenjs
     *  @param joinPoint
     *  @return Object
     *  @date 2018/10/9 22:59
     */
    @Around("vlymanLogPointCut()")
    public Object doAround(ProceedingJoinPoint joinPoint) throws Throwable {
        long startTime = System.currentTimeMillis();
        HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
        VlymanLog vlymanLog = AspectUtil.getAnnotation(joinPoint, VlymanLog.class);
        log.info("开始执行:【" + startTime + "】->" + vlymanLog.description());
        log.info("请求URL:【" + startTime + "】->" + request.getRequestURL().toString());
        log.info("执行方法:【" + startTime + "】->" + AspectUtil.getFullMethodName(joinPoint));
        try {
            Object rtnObj = joinPoint.proceed();
            long endTime = System.currentTimeMillis();
            String excuteTimeUse = ((endTime - startTime)/1000f) + "秒";
            if (vlymanLog.recordResult()) {
                log.info( "执行结果:【" + startTime  + "】->" + JSONObject.toJSONString(rtnObj));
            } else {
                log.info( "执行结果:【" + startTime  + "】->成功");
            }
            log.info( "执行耗时:【" + startTime  + "】->" +  excuteTimeUse  );
            log.info( "执行结束:【" + startTime + "】");
            return rtnObj;
        } catch (Throwable throwable) {
            long endTime = System.currentTimeMillis();
            String excuteTimeUse = ((endTime - startTime)/1000f) + "秒";
            log.error( "执行失败:【" + startTime + "】方法：" + vlymanLog.description());
            log.error( "执行耗时:【" + startTime + "】->" + excuteTimeUse );
            log.error( "执行结束:【" + startTime + "】");
            throw throwable;
        }
    }
}
